
"""A sample skeleton vehicle app."""

import asyncio
import json
import logging

from sdv.util.log import (  # type: ignore
    get_opentelemetry_log_factory,
    get_opentelemetry_log_format,
)

from sdv.vehicle_app import VehicleApp, subscribe_topic
from vehicle import Vehicle  # type: ignore

# Configure the VehicleApp logger with the necessary log config and level.
logging.setLogRecordFactory(get_opentelemetry_log_factory())
logging.basicConfig(format=get_opentelemetry_log_format())
logging.getLogger().setLevel("DEBUG")
logger = logging.getLogger(__name__)

GET_BEAM_REQUEST_TOPIC = "frontlightcontrol/setBeam/request"
GET_BEAM_RESPONSE_TOPIC = "frontlightcontrol/setBeam/response"

task = ''


class FrontLightControlApp(VehicleApp):

    def __init__(self, vehicle_client: Vehicle):
        # SampleApp inherits from VehicleApp.
        super().__init__()
        self.Vehicle = vehicle_client
        self.flag = True

    async def on_start(self):
        """Run when the vehicle app starts"""
        # This method will be called by the SDK when the connection to the
        # Vehicle DataBroker is ready.
        # Here you can subscribe for the Vehicle Signals update (e.g. Vehicle beam).

        pass

    async def on_timer(self):
        while 1:
            logging.debug("task loopping ...")
            await self.Vehicle.Body.Lights.IsLowBeamOn.set(self.flag)
            self.flag = not self.flag
            logger.info("flag is %s", self.flag)
            await asyncio.sleep(0.3)
        #     break
        # return None

    @subscribe_topic(GET_BEAM_REQUEST_TOPIC)
    async def on_get_beam_request_received(self, data_str: str) -> None:

        logger.debug(
            "PubSub event for the Topic: %s -> is received with the data: %s",
            GET_BEAM_REQUEST_TOPIC,
            data_str,
        )
        #  str -> dict
        data = json.loads(data_str)
        # get liht status
        status = data["status"]

        tasks = asyncio.all_tasks()
        for task in iter(tasks):
            name = task.get_coro().__name__
            if name == 'on_timer':
                task.cancel()
        
        if status == "close":
            await self.Vehicle.Body.Lights.IsLowBeamOn.set(False)
        elif status == "always":
            await self.Vehicle.Body.Lights.IsLowBeamOn.set(True)
        elif status == "flashing":
            loop = asyncio.get_running_loop()
            # logger.info("self.on_timer is is %", self.on_timer.__name__)
            loop.create_task(self.on_timer())

        else:

            await self.publish_event(
                GET_BEAM_RESPONSE_TOPIC,
                json.dumps(
                    {
                        "result": {
                            "status": 0,
                            "message": "invalid parameter",
                        },
                    }
                ),
            )

        await self.publish_event(
            GET_BEAM_RESPONSE_TOPIC,
            json.dumps(
                {
                    "result": {
                        "status": 0,
                        "message": f"""Current beam = {status}""",
                    },
                }
            ),
        )
